/*
PORN-OS API
The one and only way to request services from the kernel
*/

#ifndef API_H
#define API_H

#include "max_priority.h"
#include "states.h"
#include "types.h"
#include "null.h"
#include "error_codes.h"
#include "string.h"
#include "message_definition.h"
#include "system_id.h"

/* creates a new process executing the program progname and returns its pid (or -1 in case of failure. Up to four parameters can be passed to the new process using the parameters array. */
int32_t fourchette(int32_t priority, char * progname, int32_t parameters[4]);

/* kills the process pid and transmits the exit_code to its supervisors (if any) */
int32_t tuer(int32_t pid, int32_t exit_code);

/* the caller is removed from the system and exit_code is returned to its supervisors (if any) */
int32_t quitter(int32_t exit_code);

/* the caller is removed from the system and the implied exit_code (always SUCCESS) is returned to its supervisors (if any). This function is mainly used to be sure UP terminate normally even without a call to quitter() or tuer(). */
int32_t quitter_succes();

/* changes the priority of the process pid by priority */
int32_t changer_priorite(int32_t pid, int32_t priority);

/* returns the program name being executed by the process pid */
char* obtenir_programme(int32_t pid);

/* returns the pid of the current process */
int32_t obtenir_pid();

/* returns the priority of the process pid or FAILURE in case of failure */
int32_t obtenir_priorite(int32_t pid);

/* returns the state of the process pid or FAILURE in case of failure */
int32_t obtenir_etat(int32_t pid);

/* returns the parent's pid of the process pid or FAILURE in case of failure */
int32_t obtenir_parent(int32_t pid);

/* returns the list of the pids of all the processes in the system. The return value in a pointer to an array of PID (or NULL if OUT_OF_MEMORY) and length contains the number of PID in the system and thus in the array. */
int32_t* obtenir_tous_pid(int32_t* length);

/* prints string using tty0. Returns SUCCESS in case of success and FAILURE otherwise.*/
int32_t ecrire(const char* data);

/* prints string to the LCD. Returns SUCCESS in case of success and FAILURE otherwise.*/
int32_t ecrire_lcd(const char* data);

/* reads data from the user (up to length-1 characters or until a \r character is entered. Returns SUCCESS if success, FAILURE otherwise. Adds the \0 at the end of the result. */
int32_t lire(char* data, int length);

/* blocks the process pid until it is woken up using reveiller()*/
int32_t bloquer(int32_t pid);

/* the caller waits for the process pid to terminate. Returns SUCCESS if the call is a success, FAILURE otherwise. pid must be the pid of a caller's child. The return value given by the process pid at termination is transmitted to the caller using the parameter status. */
int32_t attendre(int32_t pid, int32_t* status);

/* wakes a blocked or delayed process up. */
int32_t reveiller(int32_t pid);

/* delays the process pid for n ms */
int32_t retarder(int32_t pid, uint32_t n);

/* allocates size bytes and returns a pointer to them */
void* allouer(int32_t size);

/* frees the memory pointed by pointer */
int32_t liberer(void* pointer);

/* sends a message containing a string. Returns either SUCCESS, FAILURE or OUT_OF_MEMORY. */
int32_t envoyer_chaine(int32_t to, char* data, int32_t priority);

/* sends a message containing an integer. Returns either SUCCESS, OUT_OF_MEMORY or FAILURE. */
int32_t envoyer_entier(int32_t to, int32_t data, int32_t priority);

/* sends a message containing an process_information structure. This structure is filled with information from the caller. Returns either SUCCESS, OUT_OF_MEMORY or FAILURE. */
int32_t envoyer_informations_processus(int32_t to, int32_t priority);

/* receives the first message of the message queue (or waits until one arrives).Returns SUCCESS if a message has been read, FAILURE in case of error. */
int32_t recevoir_premier(message_t* message);

/* receives the first message from the process from (or waits until one arrives). Returns SUCCESS if a message has been read, FAILURE in case of error. */
int32_t recevoir_de(int32_t from, message_t* message);

/* receives the first message with the correct priority (or waits until one arrives). Returns SUCCESS if a message has been read, FAILURE in case of error. */
int32_t recevoir_priorite(int32_t priority, message_t* message);

/* receives the first message of the message queue (or waits until either one arrives or the specified time is up). Returns SUCCESS if a message has been read, FAILURE in case of error.*/
int32_t recevoir_premier_delai(message_t* message, uint32_t timeout);

/* receives the first message from the process from (or waits until either one arrives or the specified time is up). Returns SUCCESS if a message has been read, FAILURE in case of error. */
int32_t recevoir_de_delai(int32_t from, message_t* message, uint32_t timeout);

/* receives the first message with the correct priority (or waits until either one arrives or the specified time is up). Returns SUCCESS if a message has been read, FAILURE in case of error. */
int32_t recevoir_priorite_delai(int32_t priority, message_t* message, uint32_t timeout);

/* returns the number of messages the caller has in its message queue */
int32_t obtenir_nombre_messages();

/* registers the caller as a supervisor of supervised_pid */
int32_t superviser(int32_t supervised_pid);

/* the caller stops supervising supervised_pid. Returns SUCCESS or FAILURE if supervised_pid was not one of the supervised processes.*/
int32_t stopper_supervision(int32_t supervised_pid);

/* frees mess. Must be done that way and not using liberer or there might be some memory leaks */
int32_t liberer_message(message_t mess);

/* returns the program associated with this program_id. Returns NULL in the system ran out of memory or if the program id does not match a program.  */
char* obtenir_programme_par_id(int32_t program_id);

/* returns a pseudo-random unsigned int. The method has been found online and is initialized using the parameters. The function modifies its parameters so that another call will not return the same results (if the same variables are passed). This is NOT a system call (hence the english name), the help of the kernel is not needed there. */
uint32_t random(int* m_w, int* m_z);

/* returns the help of the program program_name. Returns NULL if the system is out of memory. */
char* obtenir_programme_aide(const char* program_name);

#endif
